/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jm.jmsql.cloud;

import com.jm.jmsql.cloud.email.EmailGenerator;
import com.jm.jmsql.cloud.entities.Users;
import com.jm.jmsql.cloud.persitence.UserMaintenance;
import com.jm.jmsql.cloud.rs.Message;
import com.jm.jmsql.cloud.rs.Message.Type;
import com.jm.jmsql.cloud.rs.Result;
import com.jm.jmsql.cloud.validation.AuthenticationValidator;
import static com.jm.jmsql.cloud.validation.RegularExpressions.EMAIL_ADDRESS;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeMultipart;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

/**
 *
 * @author Marques
 */
@Path("/auth")
public class Authentication {

    /**
     *
     */
    private final AuthenticationValidator authValidator;

    /**
     *
     */
    public Authentication() {
        this.authValidator = new AuthenticationValidator();
    }

    /**
     * http://{server}/jmsql-cloud/auth/login/{user}/{password}
     *
     * @param user
     * @param password
     * @return
     */
    @GET
    @Path("login/{user}/{password}")
    @Produces({"application/xml", "application/json"})
    public Result login(@PathParam("user") String user, @PathParam("password") String password) {
        return this.authValidator.login(user.matches(EMAIL_ADDRESS), password, user.matches(EMAIL_ADDRESS) 
                                                                                    ? UserMaintenance.getInstance().getUserByEmail(user)
                                                                                        : UserMaintenance.getInstance().getUserByUsername(user));
    }

    /**
     * http://{server}/jmsql-cloud/auth/register/{user}/{password}/{email}
     *
     * @param username
     * @param password
     * @param email
     * @return
     */
    @GET
    @Path("register/{username}/{password}/{email}")
    @Produces({"application/xml", "application/json"})
    public Result register(@PathParam("username") String username, @PathParam("password") String password, @PathParam("email") String email) {
        Result result = this.authValidator.register(username, password, email);
        if (result.isSuccessful()) {
            if (!UserMaintenance.getInstance().addUser(new Users(username, password, email))) {
                result.setSuccessful(false);
                result.add(new Message(Type.ERROR, "Error adding user, contact: michaellrmarques@gmail.com"));
            }
        }
        return result;
    }

    /**
     * 
     * @param user
     * @return 
     */
    @GET
    @Path("forgotten-password/{user}")
    @Produces({"application/xml", "application/json"})
    public Result forgottenPassword(@PathParam("user") String user) {
        Users userInfo = user.matches(EMAIL_ADDRESS) ? UserMaintenance.getInstance().getUserByEmail(user)
                                                            : UserMaintenance.getInstance().getUserByUsername(user);
        if (userInfo == null) {
            return new Result(false, new Message(Type.ERROR, "User not found!"));
        }
        
        Properties properties = System.getProperties();
        properties.put("mail.smtp.ssl.trust", "smtp.gmail.com");
        properties.put("mail.smtp.starttls.enable", "true");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.port", "587");
        
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("michaellrmarques", "@Michael89");
            }
        });
        
        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress("noreply@jm-sql.com"));
            message.addRecipient(RecipientType.TO, new InternetAddress(userInfo.getEmail()));
            message.setSubject("JMSql Change Password");
            
            Map props = new HashMap();
            props.put("{username}", userInfo.getUsername());
            props.put("{change-password-link}", "http://localhost:8080/jm-sql-cloud/change-password-page/" + userInfo.getUsername());
            
            MimeMultipart multipart = new MimeMultipart("relative");
            
            EmailGenerator generator = new EmailGenerator();
            multipart.addBodyPart(generator.getHtmlBodyPart("ChangePassword", props));
            multipart.addBodyPart(generator.getImageBodyPart("logo.png"));
            
            message.setContent(multipart);
            Transport.send(message);
        } catch (IOException | MessagingException e) {
            return new Result(false, new Message(Type.ERROR, e.getMessage()));
        }
        return new Result("Email sent to " + userInfo.getEmail());
    }

    /**
     *
     * @param user
     * @param password
     * @return
     */
    @GET
    @Path("change-password/{user}/{password}")
    @Produces({"application/xml", "application/json"})
    public Result changePassword(@PathParam("user") String user, @PathParam("password") String password) {
        return new Result();
    }

    /**
     *
     * @param email
     * @return 
     */
    @GET
    @Path("verify-email-address/{email}")
    @Produces({"application/xml", "application/json"})
    public Result verifyEmailAddress(@PathParam("email") String email) {
        return new Result();
    }
    
}
